- Published on
Google Java Style Guide翻譯及重點整理
- Authors
- Name
- Ed Li
- X
導論:
- 目標明確性: 此文件定義了 Google 對 Java 程式碼的完整編碼標準。若 Java 原始碼符合此指南中的規則,則視為「Google 風格」。
- 規範重點: 文件著重於必須嚴格遵守的規則,而非提供彈性的建議,避免無法由人或工具強制執行的條款。
- **術語定義:**class: 包含「一般」類別、列舉類別、介面或註解類型 (@interface)。
- member: 指的是類別中巢狀類別、欄位、方法或建構子,但不包含初始化器和註解。
- comment: 指的是「實作」註解,不使用「文件註解」一詞,而使用「Javadoc」一詞。
- 範例非規範: 文件中的程式碼範例僅為示範,可能不是唯一的程式碼風格。
原始碼檔案基本原則:
- 檔案命名: 原始碼檔案名稱應與其包含的頂層類別名稱(且只有一個)相同,並加上 .java 副檔名。
- 檔案編碼: 原始碼檔案必須使用 UTF-8 編碼。
- 特殊字元:
- 空白字元: 原始碼檔案中除了換行符號外,ASCII 水平空格字元 (0x20) 是唯一允許出現的空白字元。這意味著:
- 字串和字元常值中的其他空白字元必須使用跳脫字元。
- 禁止使用 Tab 字元進行縮排。
- 跳脫字元: 對於擁有特殊跳脫字元的字元 (\b, \t, \n, \f, \r, \", \' 和 \\),應使用跳脫字元而非八進制或 Unicode 跳脫字元。
- 非 ASCII 字元: 針對其他非 ASCII 字元,可以使用實際的 Unicode 字元或對應的 Unicode 跳脫字元。選擇的標準是「哪個方法更容易閱讀和理解」,但強烈不建議在字串常值和註解之外使用 Unicode 跳脫字元。
- 提示: 使用 Unicode 跳脫字元時,或在實際使用 Unicode 字元時,加上解釋性註解會很有幫助。
- 提示: 不要因為擔心某些程式可能無法正確處理非 ASCII 字元,而降低程式碼的可讀性。若發生問題,該程式有 錯誤 且必須 修正。
// 範例
String unitAbbrev \= "μs"; // 最佳:即使沒有註解也很清楚
String unitAbbrev \= "\\u03bcs"; // "μs" // 允許,但沒理由這樣做
String unitAbbrev \= "\\u03bcs"; // Greek letter mu, "s" // 允許,但很笨拙且容易出錯
String unitAbbrev \= "\\u03bcs"; // 糟糕:讀者不知道這是什麼
return '\\ufeff' \+ content; // byte order mark // 良好:針對不可列印字元使用跳脫字元,並在必要時加上註解
原始碼檔案結構:
- 結構順序: 原始碼檔案應按照以下順序排列:
- 授權或版權資訊(若有)。
- package 宣告。
- import 宣告。
- 剛好一個 頂層類別。
- 分隔: 各個區塊之間用 一個空行 分隔。
- package 宣告: package 宣告 不得換行,且不適用 100 個字元的欄位限制。
- import 宣告:
- 禁止使用萬用字元 import。
- import 宣告 不得換行,且不適用 100 個字元的欄位限制。
- **順序和間距:**所有靜態 import 在單一區塊中。
- 所有非靜態 import 在單一區塊中。
- 靜態和非靜態 import 之間使用一個空行分隔。
- 區塊內按 ASCII 排序。
- 類別不使用靜態 import。
- 類別宣告:
- 剛好一個頂層類別宣告。
- 類別內容排序: 類別成員和初始化器的排序方式會影響可讀性,但沒有絕對正確的做法,每個類別都應採用 邏輯排序。
- 多載: 同名的方法應連續出現,中間不得穿插其他成員。此規則也適用於建構子,即使修飾詞 (如 static 或 private) 不同。
格式化(斷行跟縮排):
- 術語定義: 「區塊類結構」指的是類別、方法或建構子的主體。
- 大括號 :
- 強制使用大括號: if、else、for、do 和 while 敘述必須使用大括號,即使程式碼本體是空的或只包含單一敘述。
- 非空區塊: 非空區塊和區塊類結構使用 Kernighan and Ritchie 風格(「埃及括號」),也就是:
- 在開啟的大括號前不換行(以下例外)。
- 在開啟的大括號後換行。
- 在關閉的大括號前換行。
- 在關閉的大括號後換行,僅當 關閉的大括號終止敘述或終止方法、建構子或「具名」類別的主體時。
- 空區塊: 空區塊或區塊類結構可以為 K & R 風格,也可以直接關閉 ( ),除非 它是「多區塊敘述」的一部分(包含多個區塊的敘述:如 if/else 或 try/catch/finally)。
// 範例
return () \-\> { while (condition()) { method(); } };
return new MyClass() {
@Override
public void method() {
if (condition()) {
try {
something();
} catch (ProblemException e) {
recover();
}
} else if (otherCondition()) {
somethingElse();
} else {
lastThing();
}
{
int x \= foo();
frob(x);
}
}
};
// 範例
void doNothing() {} // 接受
void doNothingElse() { } // 也接受
try {
doSomething();
} catch (Exception e) {} // 不接受:多區塊敘述中不能使用簡潔空區塊
- 區塊縮排: 每開啟一個區塊或區塊類結構,縮排增加兩個空格。區塊結束時,縮排會返回上一級。縮排層級適用於程式碼和區塊中的註解。
- 每行一個敘述: 每個敘述後接換行符號。
- 欄位限制: Java 程式碼的欄位限制為 100 個字元。
- **例外:**無法遵守欄位限制的程式碼行 (例如 Javadoc 中的長 URL)。
- package 和 import 宣告。
- 可複製貼上的註解中的命令列。
- 非常長的識別符。
- 換行:
- 術語定義: 將程式碼分為多行稱為「換行」。
- 換行原則: 優先在 較高的語法層級 處斷行。
- **斷行位置:**在非賦值運算子處斷行時,斷行位置應在運算符號 之前。
- 在賦值運算子處斷行時,斷行位置應在符號 之後 (可接受)。
- 方法或建構子的名稱應與其後面的開括號 ( 相連。
- 逗號 , 應與其前面的語彙單元相連。
- lambda 中的箭頭不得斷行。
- 縮排: 換行後的每一行(「續行」)應從原始行至少縮排 4 個空格。
// 範例
MyLambda\<String, Long, Object\> lambda \= (String label, Long value, Object obj) \-\> { ... };
Predicate\<String\> predicate \= str \-\> longExpressionInvolving(str);
- 空白字元:
- 垂直空白: 單一空行通常會出現在以下位置:
- 類別中連續的成員或初始化器之間。
- 其他章節規範的地方 (例如:檔案結構、import 宣告)。
- 改善程式碼可讀性的地方。
- 水平空白: 除了程式語言或風格規則要求的空格外,以下位置 僅 出現單一 ASCII 空格:
- 在保留字和後面的開括號之間。
- 在保留字和前面的關閉大括號之間。
- 在任何開括號 { 前。
- 在二元或三元運算子的兩側。
- 在 ,:; 或型態轉換的關閉括號 ) 之後。
- 在雙斜線 // 開始的註解之前。
- 在雙斜線 // 開始的註解與註解文字之間。
- 在宣告的型態和變數之間。
- 在陣列初始化器的括號內 (可選)。
- 在型態註解和 [] 或 ... 之間。
- 水平對齊: 不強制 使用水平對齊,但允許使用。
// 範例
private int x; // 這樣很好
private Color color; // 也這樣很好
private int x; // 允許,但未來的編輯
private Color color; // 可能會讓它不對齊
- 群組括號: 除非作者和審查者都認為不使用括號不會造成誤解,否則建議使用。
- 特定結構:
- 列舉類別: 列舉常數後的逗號可選換行,也允許空行。列舉類別可以使用類似陣列初始化器的格式。
- 變數宣告:一行一個變數宣告。
- 需要時再宣告: 局部變數應在首次使用的地方附近宣告。
- 陣列:陣列初始化器: 可以選擇視為「區塊類結構」。
- 不使用 C 風格的陣列宣告: 使用 String[] args,而非 String args[]。
- switch 敘述:縮排: switch 區塊的內容與其他區塊一樣縮排 +2。
- case 縮排: case 標籤後換行,縮排層級增加 +2。
- fall-through: switch 區塊中的每個 statement 群組都應該以 break、continue、return 或拋出例外來結束,或者以註解標示會繼續執行到下一個 statement 群組。
- default 標籤: 每個 switch 敘述都應包含 default 標籤,即使它不包含任何程式碼。
- 註解:型態使用註解: 型態使用註解應出現在被註解型態之前。
- 類別註解: 類別註解應出現在文件區塊之後,且每個註解都應該在單獨一行上。
- 方法和建構子註解: 方法和建構子註解的規則與類別註解相同。
- 欄位註解: 欄位註解應出現在文件區塊之後,但可以在同一行上列出多個註解。
- 參數和局部變數註解: 除了型態使用註解,對參數和局部變數的註解沒有特殊格式化規則。
- 註解:區塊註解: 區塊註解縮排應與周圍程式碼相同。可以使用 /* ... */ 或 // ... 風格。
// 範例
switch (input) {
case 1:
case 2:
prepareOneOrTwo();
// fall through
case 3:
handleOneTwoOrThree();
break;
default:
handleLargeNumber(input);
}
- 修飾詞: 類別和成員修飾詞應按照 Java 語言規範建議的順序出現。
- 數值常值: long 型別的整數常值使用大寫 L 字尾,永遠不使用小寫 (避免與數字 1 混淆)。
命名規則:
- 通用規則: 識別符只能使用 ASCII 字母和數字,少數情況下可以使用底線。
- 識別符類型規則:
- 套件名稱: 套件名稱僅使用小寫字母和數字,不使用底線。
- 類別名稱: 類別名稱使用 UpperCamelCase (大駝峰式命名法)。
- 方法名稱: 方法名稱使用 lowerCamelCase (小駝峰式命名法)。測試方法可以使用下劃線,每個組成使用 lowerCamelCase。
- 常數名稱: 常數名稱使用 UPPER_SNAKE_CASE (大寫蛇形命名法)。
- 非常數欄位名稱: 非常數欄位名稱使用 lowerCamelCase (小駝峰式命名法)。
- 參數名稱: 參數名稱使用 lowerCamelCase (小駝峰式命名法)。
- 局部變數名稱: 局部變數名稱使用 lowerCamelCase (小駝峰式命名法)。
- 型態變數名稱: 型態變數使用單個大寫字母 (如 E, T, X, T2) 或遵循類別名稱格式加上大寫字母 T (如 RequestT, FooBarT)。
- 駝峰式命名法: 將英文片語轉換為駝峰式命名法時,遵循以下步驟:
- 將片語轉換為純 ASCII 並移除任何撇號。
- 依據空格和任何剩餘的標點符號 (通常為連字符) 將結果分為單字。
- 將所有字元轉換為小寫,然後將:
- ...每個單字的第一個字元轉換為大寫,產生 大駝峰式命名法。
- ...除了第一個字元外,將每個單字的第一個字元轉換為大寫,產生 小駝峰式命名法。
- 將所有單字串聯成單一識別符。
* // 範例
Prose form Correct Incorrect
"XML HTTP request" XmlHttpRequest XMLHTTPRequest
"new customer ID" newCustomerId newCustomerID
"inner stopwatch" innerStopwatch innerStopWatch
"supports IPv6 on iOS?" supportsIpv6OnIos supportsIPv6OnIOS
"YouTube importer" YouTubeImporter YoutubeImporter \*
"Turn on 2SV" turnOn2sv turnOn2Sv
編寫程式實作:
- @Override: 總是使用 @Override 註解標示方法。
- 捕捉的例外: 一般來說,捕捉例外但不做任何處理是不正確的。若確實不需要採取任何動作,則需要在 catch 區塊中使用註解解釋原因。
- 例外: 在測試中,若例外名稱為 expected 或以 expected 開頭,則可以忽略例外。
- 靜態成員: 引用靜態類別成員時,應使用類別名稱,而不是類別類型的參照或表達式。
- Finalizers: 不使用覆寫的 Object.finalize 方法。
Javadoc:
- 格式:基本格式: Javadoc 區塊的基本格式如範例所示。
/**
* 多行 Javadoc 文字寫在這裡,
* 正常換行...
*/
public int method(String p1) { ... }
/** 簡短的 Javadoc。 */
- 段落: 段落之間使用一個空白行,且在區塊標籤前,除了第一個段落外,其餘段落的第一個字前面要使用 <p> 標籤。
- 區塊標籤: 區塊標籤應按照 @param, @return, @throws, @deprecated 的順序排列。區塊標籤描述不得為空。若區塊標籤不適合在單行顯示,應從 @ 位置縮排四個 (或更多) 空格。
- 摘要片段: 每個 Javadoc 區塊都應以簡短的 摘要片段 開始。此片段非常重要,它會出現在類別和方法索引等地方。摘要片段應為名詞或動詞片語,而非完整的句子,並應以大寫字母開頭,並使用句點結尾。
- Javadoc 使用位置:最低限度: 每個 public 類別、public 或 protected 成員都必須有 Javadoc,除非有例外。
- 例外: 自我解釋的成員 (如 getFoo()) 可以省略 Javadoc。
- 例外: 覆寫超類別方法的 Javadoc 可以省略。
- 非必要 Javadoc: 其他類別和成員可以根據需要和期望使用 Javadoc。當使用實作註解來定義類別或成員的整體用途時,則應改用 Javadoc。
總結:
此Google Java Style Guide文件提供了詳細的規範,用於確保 Java 程式碼的風格一致性,提升程式碼的可讀性和可維護性。透過遵循這些規則,於大型專案中建立一個標準化的程式碼基礎,從而促進合作並減少錯誤。